package com.caishi.lkx.user.service.impl;

import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.util.HexUtil;

import com.caishi.lkx.common.ienum.IpType;
import com.caishi.lkx.user.model.re.SysGroupIpReModel;
import com.caishi.lkx.user.service.IGroupIpReService;
import com.googlecode.ipv6.IPv6Address;
import com.zzw.common.Wrappers;
import com.zzw.common.entity.IBSMapper;

import com.caishi.lkx.user.mapper.re.SysGroupIpReMapper;

import com.zzw.common.utils.IPUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.time.LocalDate;
import java.util.List;

@Service
public class GroupIpReServiceImpl implements IGroupIpReService {
    @Resource
    private SysGroupIpReMapper groupIpReMapper;

    @Override
    public IBSMapper<SysGroupIpReModel, Long> getMapper() {
        return groupIpReMapper;
    }

    @Override
    public void deleteByGroupId(Long groupId) {
        this.delete(Wrappers.<SysGroupIpReModel>lambdaUpdate().eq(SysGroupIpReModel::getGroupId, groupId));

    }

    @Override
    public void deleteByGroupIds(List<Long> groupIds) {
        this.delete(Wrappers.<SysGroupIpReModel>lambdaUpdate().in(SysGroupIpReModel::getGroupId, groupIds));
    }

    @Override
    public Boolean unBind(Long id) {
        return delete(id);
    }

    @Override
    public Long getGroupIdByIp(String ip) {
        var type = IPUtil.isIPv4(ip) ? IpType.ipv4 : IpType.ipv6;
        var val = type == IpType.ipv4 ? BigInteger.valueOf(Ipv4Util.ipv4ToLong(ip)) : IPv6Address.fromString(ip).toBigInteger();
        var s = getByBigInteger(val);
        return s == null ? null : s.getGroupId();
    }

    @Override
    public SysGroupIpReModel getByBigInteger(BigInteger val) {
        var x = HexUtil.encodeHexStr(SysGroupIpReModel.bigInter2Bytes(val));
        return groupIpReMapper.selectFirst(
                Wrappers.<SysGroupIpReModel>lambdaQuery()
                        .apply(String.format("val >> omask = binary 0x%s >> omask and min <= binary 0x%s and max >= binary 0x%s", x, x, x))
                        .and(w -> w.ge(SysGroupIpReModel::getEndTime, LocalDate.now())
                                .or()
                                .isNull(SysGroupIpReModel::getEndTime)
                        )
        );
    }
    @Override
    public Boolean unRelation(Long id){
      return groupIpReMapper.update(null,Wrappers.<SysGroupIpReModel>lambdaUpdate().eq(SysGroupIpReModel::getId,id).set(SysGroupIpReModel::getGroupId,null).set(SysGroupIpReModel::getBindTime,null).set(SysGroupIpReModel::getBindUserId,null))>0;
    }
}
